from concurrent.futures import ThreadPoolExecutor
from grpc import ServicerContext
from datetime import datetime
import asyncio
import grpc
from proto import TickData, DataRequest, SymbolIdentifier, MarketType
from proto import DataServiceServicer
from adapters.akshare_adapters import (
    AKShareStockAdapter,
    AKShareFutureAdapter,
    AKShareETFAdapter,
    AKShareOptionAdapter
)

class DataServiceImpl(DataServiceServicer):
    ADAPTER_MAP = {
        MarketType.STOCK: AKShareStockAdapter,
        MarketType.FUTURE: AKShareFutureAdapter,
        MarketType.ETF: AKShareETFAdapter,
        MarketType.OPTION: AKShareOptionAdapter  # 添加期权适配器映射
    }

    def __init__(self):
        self.executor = ThreadPoolExecutor(max_workers=8)

    async def GetHistoricalData(self, request: DataRequest, context: ServicerContext):
        """实现多市场类型的历史数据获取接口"""
        try:
            # 获取市场类型对应的适配器
            adapter_class = self.ADAPTER_MAP.get(request.symbol.market)
            if not adapter_class:
                context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
                context.set_details(f"不支持的市场类型: {request.symbol.market}")
                return

            # 转换时间格式
            start_time = request.start.ToDatetime()
            end_time = request.end.ToDatetime()
            
            # 获取并校验数据
            validated_data = await adapter_class.get_historical_data(
                symbol=self._format_symbol(request.symbol),
                start=start_time,
                end=end_time
            )

            # 转换为protobuf格式
            for item in validated_data:
                yield TickData(
                    timestamp=int(item['timestamp'].timestamp()),
                    price=item['close'],
                    volume=item['volume'],
                    bid_prices=[item['open']],  # 示例字段，实际需根据具体行情档位
                    ask_prices=[item['close']]
                )

        except Exception as e:
            context.set_code(grpc.StatusCode.INTERNAL)
            context.set_details(f"数据获取失败: {str(e)}")

    def _format_symbol(self, symbol: SymbolIdentifier) -> str:
        """格式化标的代码"""
        market_code = {
            MarketType.STOCK: "SH",
            MarketType.FUTURE: "CF",
            MarketType.ETF: "ETF",
            MarketType.OPTION: "OPT"  # 添加期权市场代码
        }[symbol.market]
        return f"{symbol.code.split('.')[0]}.{market_code}"